package com.googlecode.intellimars.sabotter;

import com.intellij.openapi.diagnostic.Logger;
import twitter4j.Status;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class TimeLineWrapper {
    private static final Logger LOG = Logger.getInstance("sabotter");

    // TODO:気が向いたら，これ(↓)も設定できるようにする
    private static final int MAX_STATUS = 60;   // <- 20より小さい値にするとバグる。:-)

    // 時間の降順にStatusを保存
    Map<Long, Status> friendsTimeline = new TreeMap<Long, Status>(Collections.reverseOrder());
    Map<Long, Status> repliesTimeline = new TreeMap<Long, Status>(Collections.reverseOrder());

    private int newCount;
    private Status lastStatus;
    private String ownerScreenName;
    private String ownerScreenName_w_atmark;

    public TimeLineWrapper(SabotterConfig config, List<Status> replies) {
        ownerScreenName = config.getUsername();
        ownerScreenName_w_atmark = "@" + ownerScreenName;
        for (Status status: replies) {
            repliesTimeline.put(status.getCreatedAt().getTime(), status);
        }
    }

    public void add(List<Status> timeline) {
        newCount = 0;
        for (Status status : timeline) {
            if (friendsTimeline.put(status.getCreatedAt().getTime(), status) == null) {
                // 新着分をカウント
                newCount++;
            }
            if (status.getText().startsWith(ownerScreenName_w_atmark)) {
                // 自分宛のメッセージは repliesTimeline に抜き出す
                repliesTimeline.put(status.getCreatedAt().getTime(), status);
            }
        }
        // TODO: Timeline取得できなかったときを考慮すると，闇雲にインデックス指定するのはマズいかも
        lastStatus = timeline.get(0);

        cutoff(friendsTimeline);
        cutoff(repliesTimeline);
    }

    private void cutoff(Map<Long, Status> timeline) {
        // MAX_STATUS以上は保持しない
        if (timeline.keySet().size() > MAX_STATUS) {
            Long[] keys = timeline.keySet().toArray(new Long[timeline.keySet().size()]);
            for (int i = MAX_STATUS; i < keys.length; i++) {
                timeline.remove(keys[i]);
            }
        }
    }

    public String getFriendsTimelineContents(String filterToken) {
        return getContents(friendsTimeline, filterToken);
    }
    public String getRepliesTimelineContents(String filterToken) {
        return getContents(repliesTimeline, filterToken);
    }

    private String getContents(Map<Long, Status> timeline, String filterToken) {
        // JEditorPaneにHTMLとして表示させちゃうのは，Suittarのアイデア。
        StringBuilder html = new StringBuilder();
        html.append("<html><body>");
        html.append("<table width='100%'>");
        for (Status status : timeline.values()) {
            if (status.getUser().getScreenName().startsWith(filterToken)) {
                html.append(statusContent(status));
            }
        }
        html.append("</table>");
        html.append("</body></html>");
        return String.valueOf(html);
    }

    private StringBuilder statusContent(Status status) {
        boolean isMyReply = status.getText().startsWith(ownerScreenName_w_atmark);
        boolean isMyStatus = ownerScreenName.equals(status.getUser().getScreenName());
        StringBuilder html = new StringBuilder();
        html.append("<tr");
        html.append(isMyReply ? " bgcolor='#ffffee'>" : isMyStatus ? " bgcolor='#eeeeee'>" : ">");
        html.append("<td witdh='48' valign='top'>");

        if (!isMyStatus) html.append("<a href='http://sabotter/reply?id=").append(status.getUser().getScreenName()).append("'>");
        html.append("<img border='0' src='").append(status.getUser().getProfileImageURL()).append("'>");
        if (!isMyStatus) html.append("</a>");
        
        html.append("</td><td valign='top'>");

        if (!isMyStatus) html.append("<b>").append(status.getUser().getScreenName()).append("</b> ");
        
        html.append(status.getText().replaceAll("(http://|https://){1}[\\w\\.\\-/:\\?=&]+","<a href='$0'>$0</a>"));
        html.append("<br><font color='#888888'>");
        html.append(status.getCreatedAt());
        html.append("</font></td></tr>");

        return html;
    }

    public boolean hasNewMessage() {
        return newCount > 0;
    }

    public String whatNew() {
        StringBuilder html = new StringBuilder();
        html.append("<html><body>");
        html.append("<table width='100%'>");
        html.append(statusContent(lastStatus));
        if (newCount > 1) {
            html.append("<tr><td colspan='2' align='right'>");
            html.append("<b>more ").append(newCount - 1).append(" message(s)");
            html.append("</td></tr>");
        }
        html.append("</table>");
        html.append("</body></html>");
        return String.valueOf(html);
    }

}
